#include <algorithm>
#include "point.h"
#include "interval.h"
#include "boost/numeric/interval.hpp"

int eps_turn(const point& a, const point& b, const point& c)
{
   double eps = 4 * std::numeric_limits<double>::epsilon() * (std::abs((b.x - a.x) * (c.y - a.y)) + std::abs((b.y - a.y) * (c.x - a.x)));
   double turn = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);

   if (turn > eps)
      return 1;
   else if (turn < -eps)
      return -1;
   else
      return 0;
}

using namespace boost::numeric::interval_lib;
typedef boost::numeric::interval<double> interval;

int interval_turn(const point& a, const point& b, const point& c)
{
   interval turn = (interval(b.x) - interval(a.x)) * (interval(c.y) - interval(a.y)) - (interval(b.y) - interval(a.y)) * (interval(c.x) - interval(a.x));
   interval eps(0.0);

   if (cergt(turn, eps))
      return 1;
   if (cerlt(turn, eps))
      return -1;
   return 0;
}

bool bounding_box_check(const point& a, const point& b, const point& c, const point& d)
{
   double min = std::min(a.x, b.x);
   double max = std::max(a.x, b.x);
   interval x1(min, max);

   min = std::min(c.x, d.x);
   max = std::max(c.x, d.x);
   interval x2(min, max);

   min = std::min(a.y, b.y);
   max = std::max(a.y, b.y);
   interval y1(min, max);

   min = std::min(c.y, d.y);
   max = std::max(c.y, d.y);
   interval y2(min, max);

   return (cergt(x1, x2) || cerlt(x1, x2) || cergt(y1, y2) || cerlt(y1, y2));
}